using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.Windows;
using System.Windows.Ink;
using WozLib.UI.Ink.SketchObjects;


namespace WozLib.UI.Ink.SketchCommands
{
  public class ClearSketchCommand : RememberSketchCommand
  {
    

    [XmlIgnore]
    public List<UIElement> Children
    {
      get { return _Children; }
      set { _Children = value; }
    } private List<UIElement> _Children;

    [XmlIgnore]
    public List<UIElement> InFrontChildren
    {
      get { return _InFrontChildren; }
      set { _InFrontChildren = value; }
    } private List<UIElement> _InFrontChildren;
    
    [XmlIgnore]
    public StrokeCollection StrokeCollection
    {
      get { return _StrokeCollection; }
      set { _StrokeCollection = value; }
    } private StrokeCollection _StrokeCollection;

    [XmlIgnore]
    public SketchObjectRegistry WozObjectRegistry
    {
      get { return _WozObjectRegistry; }
      set { _WozObjectRegistry = value; }
    } private SketchObjectRegistry _WozObjectRegistry;

    

    //private void RegisterClientObject(IWozObject wozObject)
    //{
    //  long id = long.MinValue;

    //  // lock on Woz Object Dictionary so we can prevent handing out duplicate IDs
    //  lock (dummy)
    //  {
    //    // Get the next ID
    //    id = _NextClientID;

    //    // Increment the next ID
    //    _NextClientID++;
    //  }

    //  RegisterObject(wozObject, id);

    //  Debug.WriteLine("Registered " + wozObject.ToString() + " with ID: " + id.ToString());
    //}

    public ClearSketchCommand()
    {
    }

    public ClearSketchCommand(bool dummy)
    {
      RegisterObject();
    }

    public override void Redo()
    {
      if (this.WozClientCommandReferences != null && 
        this.WozClientCommandReferences.InkCanvas != null && 
        this.WozClientCommandReferences.WozObjectRegistry != null)
      {
        RegisterObject();

          //todo
          // This will need to be slightly modified when we also have layers

        // save the state of Children, Strokes, WozObjectRegistry

        // Since the original list is ordered this could be WRONG if we don't do it in the right order
        // (but i think it's right here)
        Children = new List<UIElement>(WozClientCommandReferences.InkCanvas.Children.Count);
        foreach (UIElement uie in WozClientCommandReferences.InkCanvas.Children)
        {
          Children.Add(uie);
        }

        InFrontChildren = new List<UIElement>();
        if (WozClientCommandReferences.InFrontInkCanvas != null)
        {
          foreach (UIElement uie in WozClientCommandReferences.InFrontInkCanvas.Children)
          {
            if (uie is ISketchObject)
            {
              InFrontChildren.Add(uie);
            }
          }
        }

        StrokeCollection = WozClientCommandReferences.InkCanvas.Strokes;
        WozObjectRegistry = WozClientCommandReferences.WozObjectRegistry;

        // clear out all the collections
        this.WozClientCommandReferences.InkCanvas.Children.Clear();

        if (WozClientCommandReferences.InFrontInkCanvas != null)
        {
          List<UIElement> toRemove = new List<UIElement>();
          foreach (UIElement uie in WozClientCommandReferences.InFrontInkCanvas.Children)
          {
            if (uie is ISketchObject)
            {
              toRemove.Add(uie);
            }
          }
          foreach (UIElement uie in toRemove)
          {
            WozClientCommandReferences.InFrontInkCanvas.Children.Remove(uie);
          }
        }

        this.WozClientCommandReferences.InkCanvas.Strokes = new StrokeCollection();

        // create a new SketchObjectRegistry and assign it to the client ink canvas
        // and the wozClientCommandReferences
        SketchObjectRegistry sketchObjectRegistry = new SketchObjectRegistry();
        this.WozClientCommandReferences.InkCanvas.SketchObjectRegistry = sketchObjectRegistry;
        this.WozClientCommandReferences.WozObjectRegistry = sketchObjectRegistry;

      }
    }

    public override void Undo()
    {
      RememberSketchCommand wcrc = GetCommand(WozClientClearCommandID);
      if (wcrc != null && wcrc is ClearSketchCommand)
      {
        ClearSketchCommand wccc = wcrc as ClearSketchCommand;
        if (wccc != null && wccc.Children != null)
        {
          wccc.WozClientCommandReferences.InkCanvas.Children.Clear();
          foreach (UIElement uie in wccc.Children)
          {
            wccc.WozClientCommandReferences.InkCanvas.Children.Add(uie);
          }

          if (WozClientCommandReferences.InFrontInkCanvas != null)
          {
            // clear
            List<UIElement> toRemove = new List<UIElement>();
            foreach (UIElement uie in WozClientCommandReferences.InFrontInkCanvas.Children)
            {
              if (uie is ISketchObject)
              {
                toRemove.Add(uie);
              }
            }
            foreach (UIElement uie in toRemove)
            {
              WozClientCommandReferences.InFrontInkCanvas.Children.Remove(uie);
            }

            // add
            foreach (UIElement uie in wccc.InFrontChildren)
            {
              wccc.WozClientCommandReferences.InFrontInkCanvas.Children.Add(uie);
            }
          }

          this.WozClientCommandReferences.InkCanvas.Strokes = wccc.StrokeCollection;

          this.WozClientCommandReferences.WozObjectRegistry = wccc.WozObjectRegistry;
          this.WozClientCommandReferences.InkCanvas.SketchObjectRegistry = wccc.WozObjectRegistry;
        }
      }
    }
  }
}
